#include "includes.h"




static ELEMENT_PS pstConfig_list = NULL;


static int format_print_map(char *buff, int length, MOMAP_PS pstMap, int cnt)
{
	int i;
	int offset = 0;
	int len;
	if (length <= 1)
		return 0;
	for (i=0; i<cnt; i++)
	{
		len = snprintf(buff+offset, length-offset, "  %s:<%s>  ", pstMap[i].index, pstMap[i].addr);
		offset += len;
	}
	return offset;
}

static int my_strcpy(char *buff, int length, char *str, int str_len)
{
	int len;
	if (length == 0)
		return 0;
	len = min(length, str_len);
	memcpy(buff, str, len);
	return len;
}

int format_print(char *buff, int length)
{
	int offset = 0;
	int len;
	ELEMENT_PS pstElement;

	pstElement = pstConfig_list;
	while(pstElement)
	{
		len = my_strcpy(buff+offset, length-offset, "module:", strlen("module:"));
		offset += len;
		len = my_strcpy(buff+offset, length-offset, pstElement->name, strlen(pstElement->name));
		offset += len;
		len = format_print_map(buff+offset, length-offset, pstElement->pstMap, pstElement->count);
		offset += len;
		len = my_strcpy(buff+offset, length-offset, "\n", 1);
		offset += len;
		pstElement = pstElement->pnext;
	}
	len = min(offset, length-1);
	buff[len] = '\0';
	return 0;
}

#define BUFF_INFO_PRINT 1024
void print_info()
{
	char *buff;
	buff = Malloc(BUFF_INFO_PRINT);
	format_print(buff, BUFF_INFO_PRINT);
	if (wnd_info)
		SetWindowText(wnd_info, buff);
	free(buff);
}

static int element_decode_node(mxml_node_t *head, ELEMENT_PS pstElement)
{
	int i;
	int cnt;
	mxml_node_t *pstNode, *pstTop;
	MOMAP_PS pstMap;
	const char *name, *value;

	pstElement->flag = CONFIG_ISOK;
	pstNode= mxmlFindElement(head, head, "element", "attr", pstElement->name, MXML_DESCEND);
	if (pstNode == NULL)
	{
		err_msg("can not find the %s node", pstElement->name);
		pstElement->flag = CONFIG_ISERR_NODE;
		return -1;
	}

	cnt = pstElement->count;
	pstMap = pstElement->pstMap;
	pstTop = pstNode;
	
	for (i=0; i<cnt; i++)
	{
		pstMap[i].flag = MOMAP_ISCLEAN;
	}

	while ((pstNode=mxmlWalkNext(pstNode, pstTop, MXML_DESCEND)) != NULL)
	{
		if ((name = mxmlGetElement(pstNode))==NULL || (value = mxmlGetText(pstNode, 0))==NULL)
			continue;
		for (i=0; i<cnt; i++)
		{
			if (pstMap[i].flag == MOMAP_ISCLEAN && !strcmp(name, pstMap[i].index))
			{
				strncpy(pstMap[i].addr, value, pstMap[i].len);
				pstMap[i].flag = MOMAP_ISDIRTY;
			}
		}
	}

	for (i=0; i<cnt; i++)
	{
		if (pstMap[i].flag == MOMAP_ISCLEAN)
		{
			err_msg("can not find the %s", pstMap[i].index);
			pstElement->flag = CONFIG_ISERR_ELEMENT;
			return -1;
		}
	}

	return 0;
	
}

/*
static ELEMENT_PS element_add_list(ELEMENT_PS pstHead, ELEMENT_PS pstAdd)
{
	ELEMENT_PS *ppstTemp;
	
	if (pstHead == NULL)
	{
		pstHead = pstAdd;
		pstHead->pnext = NULL;
		return pstHead;
	}
	ppstTemp = &pstHead->pnext;
	while (*ppstTemp)
	{
		ppstTemp = &(*ppstTemp)->pnext;
	}
	*ppstTemp = pstAdd;
	pstAdd->pnext = NULL;
	return pstHead;
}
*/

int add_configure(ELEMENT_PS pstAdd)
{
	ELEMENT_PS *ppstTemp;
	
	if (pstConfig_list == NULL)
	{
		pstConfig_list = pstAdd;
		pstConfig_list->pnext = NULL;
		return 0;
	}

	ppstTemp = &pstConfig_list->pnext;
	while (*ppstTemp)
	{
		ppstTemp = &(*ppstTemp)->pnext;
	}
	*ppstTemp = pstAdd;
	pstAdd->pnext = NULL;
	return 0;
}


int load_configure()
{
	ELEMENT_PS pstElement;
	mxml_node_t *pstTree;
	//mxml_node_t *pstTop;
	//mxml_node_t *pstNode;
	
	int off;
	FILE *fp;

	char path[100];
	strncpy(path, CFGPATH, sizeof(path));
	off = strlen(path);
	if (local_get_cfgname(path+off, sizeof(path)-off)<0)
		return -1;
	fp = Fopen(path, "r");
	pstTree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
	if (pstTree == NULL)
		return -1;
	

	
	pstElement = pstConfig_list;
	while(pstElement)
	{
		element_decode_node(pstTree, pstElement);
		pstElement = pstElement->pnext;
	}

	//printf("load ok\n");
	Fclose(fp);
	mxmlDelete(pstTree);
	return 0;
}


/*
int load_configure(mxml_node_t *head)
{
	ELEMENT_PS pstTemp;
	pstTemp = pstConfig_list;
	while(pstTemp)
	{
		element_decode_node(head, pstTemp);
		pstTemp = pstTemp->pnext;
	}
	return 0;
}
*/

static const char *whitespace_cb(mxml_node_t *node, int where)
{
	if (mxmlGetElement(node) && where==MXML_WS_AFTER_CLOSE)
		return ("\n");
	else
		return (NULL);
}


int save_configure(char *file_name)
{
	FILE *fp;
	int i;
	int cnt;
	mxml_node_t *pstXml, *pstNode, *pstTree, *pstElement, *pstConfig;
	ELEMENT_PS pstItem;
	MOMAP_PS pstMap;
	char path[100];
	int off;
	
	pstTree = mxmlNewXML("1.0");
	pstXml = mxmlNewElement(pstTree, "xml");
	pstConfig = mxmlNewElement(pstXml, "configure");
	pstItem = pstConfig_list;
	while(pstItem)
	{
		pstElement = mxmlNewElement(pstConfig, "element");
		mxmlElementSetAttr(pstElement, "attr", pstItem->name);;
		pstMap = pstItem->pstMap;
		cnt = pstItem->count;
		for (i=0; i<cnt; i++)
		{
			pstNode = mxmlNewElement(pstElement, pstMap[i].index);
			mxmlNewText(pstElement, 0, pstMap[i].addr);
		}
		pstItem = pstItem->pnext;
	}


		
	strncpy(path, CFGPATH, sizeof(path));
	off = strlen(path);
	strncpy(path+off, file_name, sizeof(path)-off);
	
	fp = Fopen(path, "w");
	mxmlSaveFile(pstTree, fp, whitespace_cb);
	Fclose(fp);
	mxmlDelete(pstTree);
	return 0;
}


int copy_cfg(HWND hDlg, MOMAP_PS pstMap, int cnt)
{
	int i;
	//char buff[200];
	//unsigned char mac[6];
	int a;
	float b;
	int len;
	struct in_addr addr;
	
	for(i=0; i<cnt; i++)
	{

		switch(pstMap[i].type)
		{
			case IS_ADDR_IP:
				len = GetWindowText(GetDlgItem(hDlg, pstMap[i].id), pstMap[i].addr, pstMap[i].len);
				if (len <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input can not be nothing");
					return -1;
				}
				if (len >= pstMap[i].len-1)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input is too long");
					return -1;
				}
				if (inet_pton(AF_INET, pstMap[i].addr, (void *)&addr) <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR!format is wrong");
					return -1;
				}
				
				break;
			case IS_ADDR_MAC:
				len = GetWindowText(GetDlgItem(hDlg, pstMap[i].id), pstMap[i].addr, pstMap[i].len);
				if (len <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input can not be nothing");
					return -1;
				}
				if (len >= pstMap[i].len-1)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input is too long");
					return -1;
				}
				if ((len = Is_mac_addr(pstMap[i].addr)) != 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR!format is wrong");
					return -1;
				}
				break;
			case IS_ENABLE:
				if (IsDlgButtonChecked(hDlg, pstMap[i].id) == BST_CHECKED)
				{
					strncpy(pstMap[i].addr, "enable", pstMap[i].len);
				}
				else
				{
					strncpy(pstMap[i].addr, "disable", pstMap[i].len);
				}
				break;
			case IS_FLOAT:
				len = GetWindowText(GetDlgItem(hDlg, pstMap[i].id), pstMap[i].addr, pstMap[i].len);
				if (len <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input can not be nothing");
					return -1;
				}
				if (len >= pstMap[i].len-1)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input is too long");
					return -1;
				}
				if (sscanf(pstMap[i].addr, "%f", &b) == 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR!format is wrong");
					return -1;
				}
				break;
			case IS_INTEGER:
				len = GetWindowText(GetDlgItem(hDlg, pstMap[i].id), pstMap[i].addr, pstMap[i].len);
				if (len <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input can not be nothing");
					return -1;
				}
				if (len >= pstMap[i].len-1)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input is too long");
					return -1;
				}
				if (sscanf(pstMap[i].addr, "%d", &a) == 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR!format is wrong");
					return -1;
				}
				break;
			case IS_STRING:
				len = GetWindowText(GetDlgItem(hDlg, pstMap[i].id), pstMap[i].addr, pstMap[i].len);
				if (len <= 0)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input can not be nothing");
					return -1;
				}
				if (len >= pstMap[i].len-1)
				{
					SetWindowText(GetDlgItem(hDlg, pstMap[i].id), "ERROR! input is too long");
					return -1;
				}
				break;
		}
	}

	return 0;
}

